/*
 * Dataset.cpp
 *
 *  Created on: Jan 15, 2011
 *      Author: LyonsDesktop
 */
#include "Dataset.h"
#include "Formats/CSV.h"


#include <iostream>
#include <algorithm>
#include "../XML.h"

using namespace XML;
using namespace CLEVER::Datasets;
/*class Attribute
{
public:
	void ClearKeys();
};*/
void Attribute::ClearKeys() { }

void Attribute::RemoveKey(std::string& rkey)
{
	for (unsigned int i = 0; i < Keys.size(); i++)
	{
		if (Keys[i] == rkey)
		{
			Keys.erase(Keys.begin() + i--);
		}
	}
}

void Attribute::RemoveKeys(std::vector<std::string>& rkeys)
{
	for (unsigned int i = 0; i < rkeys.size(); i++)
	{
		RemoveKey(rkeys[i]);
	}
}

void Attribute::AddKey(std::string& rkey)
{
	Keys.push_back(rkey);
}

void Attribute::AddKeys(std::vector<std::string>& rkeys)
{
	for (unsigned int i = 0; i < rkeys.size(); i++)
	{
		Keys.push_back(rkeys[i]);
	}
}

std::string Attribute::GetKey(int index)
{
	return ((unsigned int)index < Keys.size()) ? Keys[index] : "";
}

int Attribute::GetIndex(std::string& key)
{
	for (unsigned int i = 0; i < Keys.size(); i++)
	{
		if (Keys[i] == key)
		{ return i; }
	}

	return -1;
}

//! Reads an attribute from an XML element.
CLEVER::Datasets::Attribute ReadAttribute(Element* attr)
{
        Element::Parameter* classname = attr->GetParameter("classname");
        Element* valueslist = attr->GetElement("values");
        CLEVER::Datasets::Attribute a;
        if (classname) { a.Name = classname->Value; }
        if (valueslist && valueslist->GetParameter("type") && valueslist->GetParameter("type")->Value == "list")
        {
                Element* valueitem = valueslist->GetElement("item");
                while (valueitem)
                {
                        Element::Parameter* valueparam = valueitem->GetParameter("value");
                        if (valueparam)
                        {
                                a.AddKey(valueparam->Value);
                        }
                        valueitem = valueslist->GetElement("item", valueitem);
                }
        }
        return a;
}

CLEVER::Datasets::Attribute ReadAttribute(Element* attr);

Dataspec::Dataspec(const char* srcfile)
{
        std::ifstream ifile(srcfile);
        if (!ifile) { return; }

        std::stringstream sstr;
        sstr << ifile.rdbuf();
        ifile.close();

        std::string tempString=sstr.str();
        XML::Body* xmlbody = new XML::Body(tempString);
        //xmlbody->root->WriteTo(std::cout);

        Element* spec = xmlbody->root->GetElement("DatasetSpecification");
        if (!spec) { delete xmlbody; return; }

        Element* attrspec = spec->GetElement("AttributeSpecification");
        if (!attrspec) { delete xmlbody; return; }

        Element* data_attr = attrspec->GetElement("DataAttributes");
        if (data_attr)
        {
                Element* attr = data_attr->GetElement("AttributeFactory");
                while (attr)
                {
                        RealAttributes.push_back(ReadAttribute(attr));
                        attr = data_attr->GetElement("AttributeFactory", attr);
                }
        }
        Element* meta_attr = attrspec->GetElement("MetaAttributes");
        if (data_attr)
        {
                Element* attr = meta_attr->GetElement("AttributeFactory");
                while (attr)
                {
                        MetaAttributes.push_back(ReadAttribute(attr));
                        attr = meta_attr->GetElement("AttributeFactory", attr);
                }
        }

        delete xmlbody;
}

/*
template <typename T>
Dataspec::Dataspec( CLEVER::Datasets::Dataset<T>* dataset)
{
        for (int i = 0; i < dataset->RealData.attributes.size(); i++)
        {
                RealAttributes.push_back(dataset->RealData.attributes[i]);
        }
        for (int i = 0; i < dataset->MetaData.attributes.size(); i++)
        {
                MetaAttributes.push_back(dataset->MetaData.attributes[i]);
        }
}
*/
